<?php
/**
 * Created by PhpStorm.
 * User: august
 * Date: 2021/4/2
 * Time: 10:44
 */

namespace Aug\Tools\Exporter;


use Aug\Tools\Exception\NotSupportException;
use Aug\Tools\Exporter\Csv;
use Aug\Tools\Zip;

class Exporter
{
    const ERROR_TYPE = '错误：类型不支持';
    /**
     * @var ExporterInterface 驱动 Csv
     */
    protected $driver;

    /**
     * @var csv / excel 等
     */
    protected $type = 'csv';
    protected $allowTypes = ['csv', 'excel', 'excel98'];
    protected $extMaps = [
        'csv' => 'csv',
        'excel' => 'xlsx',
        'excel98' => 'xls',
    ];

    /**
     * @var bool 是否压缩
     */
    protected $isZip = false;
    /**
     * @var int 压缩等级
     */
    protected $zipLevel = 1;

    /**
     * @var string 导出文件名
     */
    protected $fileName;

    /**
     * @var array 初始化参数
     */
    protected $params = [];

    public function __construct($params = [])
    {
        $this->params = $params;
        if (!empty($params['type'])) {
            $this->setType($params['type']);
            unset($params['type']);
        }

        if (!empty($params['isZip'])) {
            $this->setIsZip($params['isZip'], $params['zipLevel'] ?? 1);
            unset($params['isZip'], $params['zipLevel']);
        }
    }

    public function setType(string $type)
    {
        $type = strtolower($type);
        if (!in_array($type, $this->allowTypes)) {
            throw new NotSupportException(self::ERROR_TYPE);
        }
        $this->type = $type;
        return $this;
    }

    public function setIsZip($isZip = false, $level = 1)
    {
        $this->isZip = $isZip;
        if ($isZip && $level) {
            $this->zipLevel = $level;
        }
        return $this;
    }

    public function setFileName($fileName)
    {
        $this->fileName = $fileName;
    }

    public function getFileName()
    {
        $file = ($this->fileName ?? date('Ymd_His')) . '.' . $this->extMaps[$this->type];
        if ($this->isZip) {
            $file .= '.zip';
        }
        return $file;
    }

    private function initDriverByType()
    {
        if ($this->type === 'csv') {
            $this->driver = new Csv($this->params);
        } else {
            echo "todo";die;
        }
    }

    public function addRow($data)
    {
        if (is_null($this->driver)) {
            $this->initDriverByType();
        }
        $this->driver->addRow($data);
        return $this;
    }

    public function output($unlink = true)
    {
        $tmpFile = $oldTmp = $this->driver->getFile();
        if ($this->isZip) {
            $tmpFile = Zip::zipFile($tmpFile, $this->getFileName());
            @unlink($oldTmp);
        }
        $this->setExportHeader($tmpFile);
        $unlink && @unlink($tmpFile);
    }

    public function setExportHeader($originalFile)
    {
        $mimetypes = [
            'doc' => 'application/msword',
            'bin' => 'application/octet-stream',
            'exe' => 'application/octet-stream',
            'so' => 'application/octet-stream',
            'dll' => 'application/octet-stream',
            'pdf' => 'application/pdf',
            'ai' => 'application/postscript',
            'xls' => 'application/vnd.ms-excel',
            'xlsx' => 'application/vnd.ms-excel',
            'ppt' => 'application/vnd.ms-powerpoint',
            'dir' => 'application/x-director',
            'js' => 'application/x-javascript',
            'swf' => 'application/x-shockwave-flash',
            'xhtml' => 'application/xhtml+xml',
            'xht' => 'application/xhtml+xml',
            'zip' => 'application/zip',
            'mid' => 'audio/midi',
            'midi' => 'audio/midi',
            'mp3' => 'audio/mpeg',
            'rm' => 'audio/x-pn-realaudio',
            'rpm' => 'audio/x-pn-realaudio-plugin',
            'wav' => 'audio/x-wav',
            'bmp' => 'image/bmp',
            'gif' => 'image/gif',
            'jpeg' => 'image/jpeg',
            'jpg' => 'image/jpeg',
            'png' => 'image/png',
            'css' => 'text/css',
            'html' => 'text/html',
            'htm' => 'text/html',
            'txt' => 'text/plain',
            'xsl' => 'text/xml',
            'xml' => 'text/xml',
            'mpeg' => 'video/mpeg',
            'mpg' => 'video/mpeg',
            'avi' => 'video/x-msvideo',
            'movie' => 'video/x-sgi-movie',
            'csv' => 'text/csv',
        ];

        header("Content-type:" . $mimetypes[$this->extMaps[$this->type]]);
        header("Content-Disposition:attachment;filename=" . basename($this->getFileName()));  //attachment 附件下载; inline:在线打开
        header('Cache-Control:must-revalidate,post-check=0,pre-check=0');
        header('Expires:0');
        header('Pragma:public');
        header('Content-Length:' . filesize($originalFile));
        readfile($originalFile);
    }

}